package IOdevices;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import kernel.CPU;

import adt.CPUprocess;

/**
 * This class simulates a disk.
 * 
 * @author Aaron Fung
 * 		   Chris Ren
 *
 */
public class SimulatedDisk extends Thread {
	
	/**
	 * A constant used to randomly determine how long
	 * it will take for the simulated disk to finish
	 * its service request.
	 */
	private final static int SERVICE_TIME = 10000;
	
	/**
	 * The simulated disk blocked queue used to store processes
	 * requesting for service.
	 */
	private BlockingQueue<CPUprocess> my_ioblocked_queue;
	
	/**
	 * The CPU
	 */
	private CPU my_cpu;
	
	/**
	 * A Process requesting service from the disk.
	 */
	private CPUprocess process;
	

	/**
	 * Constructor for the Simulated Disk.
	 * 
	 * @param the_cpu Reference to the CPU.
	 */
	public SimulatedDisk(final CPU the_cpu) {
		my_cpu = the_cpu;
		my_ioblocked_queue = new LinkedBlockingQueue<CPUprocess>();
	}
	
	public void start()
	{
		System.out.println("Disk Device Activated.");
		super.start();
	}
	
	/**
	 * Start the simulated disk service.
	 */
	public void run() 
	{
		while(true)
		{
			if(!my_ioblocked_queue.isEmpty()) {
				try {
					Thread.sleep(SERVICE_TIME);
					//initiateInterrupt();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				CPUprocess temp = my_ioblocked_queue.poll();
				my_cpu.process_ready(temp);
				System.out.println("Disk Service is complete for " + temp.getPid());
				
			}
		}
		
	}
	
	/**
	 * Adds a process to the blocked queue.
	 * 
	 * @param the_process The process requesting service
	 * 		  from the disk.
	 */
	public void addProcess(final CPUprocess the_process) {
		process = the_process;
		my_ioblocked_queue.add(process);
	}
	
	
	

	/**
	 * Displays current processes in the disk's
	 * blocked queue.
	 */
	public void display() {
		System.out.println("\nDisk Blocked Queue:");
		for(CPUprocess p : my_ioblocked_queue)
		{
			System.out.print(p.getPid() + ", ");
		}
	}

}
